//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2022 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

import Foundation
import SotoCore

extension ChimeSDKIdentity {
    // MARK: Enums

    public enum AllowMessages: String, CustomStringConvertible, Codable, _SotoSendable {
        case all = "ALL"
        case none = "NONE"
        public var description: String { return self.rawValue }
    }

    public enum AppInstanceUserEndpointType: String, CustomStringConvertible, Codable, _SotoSendable {
        case apns = "APNS"
        case apnsSandbox = "APNS_SANDBOX"
        case gcm = "GCM"
        public var description: String { return self.rawValue }
    }

    public enum EndpointStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case active = "ACTIVE"
        case inactive = "INACTIVE"
        public var description: String { return self.rawValue }
    }

    public enum EndpointStatusReason: String, CustomStringConvertible, Codable, _SotoSendable {
        case invalidDeviceToken = "INVALID_DEVICE_TOKEN"
        case invalidPinpointArn = "INVALID_PINPOINT_ARN"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct AppInstance: AWSDecodableShape {
        /// The ARN of the messaging instance.
        public let appInstanceArn: String?
        /// The time at which an AppInstance was created. In epoch milliseconds.
        public let createdTimestamp: Date?
        /// The time an AppInstance was last updated. In epoch milliseconds.
        public let lastUpdatedTimestamp: Date?
        /// The metadata of an AppInstance.
        public let metadata: String?
        /// The name of an AppInstance.
        public let name: String?

        public init(appInstanceArn: String? = nil, createdTimestamp: Date? = nil, lastUpdatedTimestamp: Date? = nil, metadata: String? = nil, name: String? = nil) {
            self.appInstanceArn = appInstanceArn
            self.createdTimestamp = createdTimestamp
            self.lastUpdatedTimestamp = lastUpdatedTimestamp
            self.metadata = metadata
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceArn = "AppInstanceArn"
            case createdTimestamp = "CreatedTimestamp"
            case lastUpdatedTimestamp = "LastUpdatedTimestamp"
            case metadata = "Metadata"
            case name = "Name"
        }
    }

    public struct AppInstanceAdmin: AWSDecodableShape {
        /// The AppInstanceAdmin data.
        public let admin: Identity?
        /// The ARN of the AppInstance for which the user is an administrator.
        public let appInstanceArn: String?
        /// The time at which an administrator was created.
        public let createdTimestamp: Date?

        public init(admin: Identity? = nil, appInstanceArn: String? = nil, createdTimestamp: Date? = nil) {
            self.admin = admin
            self.appInstanceArn = appInstanceArn
            self.createdTimestamp = createdTimestamp
        }

        private enum CodingKeys: String, CodingKey {
            case admin = "Admin"
            case appInstanceArn = "AppInstanceArn"
            case createdTimestamp = "CreatedTimestamp"
        }
    }

    public struct AppInstanceAdminSummary: AWSDecodableShape {
        /// The details of the AppInstanceAdmin.
        public let admin: Identity?

        public init(admin: Identity? = nil) {
            self.admin = admin
        }

        private enum CodingKeys: String, CodingKey {
            case admin = "Admin"
        }
    }

    public struct AppInstanceRetentionSettings: AWSEncodableShape & AWSDecodableShape {
        /// The length of time in days to retain the messages in a channel.
        public let channelRetentionSettings: ChannelRetentionSettings?

        public init(channelRetentionSettings: ChannelRetentionSettings? = nil) {
            self.channelRetentionSettings = channelRetentionSettings
        }

        public func validate(name: String) throws {
            try self.channelRetentionSettings?.validate(name: "\(name).channelRetentionSettings")
        }

        private enum CodingKeys: String, CodingKey {
            case channelRetentionSettings = "ChannelRetentionSettings"
        }
    }

    public struct AppInstanceSummary: AWSDecodableShape {
        /// The AppInstance ARN.
        public let appInstanceArn: String?
        /// The metadata of the AppInstance.
        public let metadata: String?
        /// The name of the AppInstance.
        public let name: String?

        public init(appInstanceArn: String? = nil, metadata: String? = nil, name: String? = nil) {
            self.appInstanceArn = appInstanceArn
            self.metadata = metadata
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceArn = "AppInstanceArn"
            case metadata = "Metadata"
            case name = "Name"
        }
    }

    public struct AppInstanceUser: AWSDecodableShape {
        /// The ARN of the AppInstanceUser.
        public let appInstanceUserArn: String?
        /// The time at which the AppInstanceUser was created.
        public let createdTimestamp: Date?
        /// The time at which the AppInstanceUser was last updated.
        public let lastUpdatedTimestamp: Date?
        /// The metadata of the AppInstanceUser.
        public let metadata: String?
        /// The name of the AppInstanceUser.
        public let name: String?

        public init(appInstanceUserArn: String? = nil, createdTimestamp: Date? = nil, lastUpdatedTimestamp: Date? = nil, metadata: String? = nil, name: String? = nil) {
            self.appInstanceUserArn = appInstanceUserArn
            self.createdTimestamp = createdTimestamp
            self.lastUpdatedTimestamp = lastUpdatedTimestamp
            self.metadata = metadata
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceUserArn = "AppInstanceUserArn"
            case createdTimestamp = "CreatedTimestamp"
            case lastUpdatedTimestamp = "LastUpdatedTimestamp"
            case metadata = "Metadata"
            case name = "Name"
        }
    }

    public struct AppInstanceUserEndpoint: AWSDecodableShape {
        /// Boolean that controls whether the AppInstanceUserEndpoint is opted in to receive messages. ALL indicates the endpoint will receive all messages.  NONE indicates the endpoint will receive no messages.
        public let allowMessages: AllowMessages?
        /// The ARN of the AppInstanceUser.
        public let appInstanceUserArn: String?
        /// The time at which an AppInstanceUserEndpoint was created.
        public let createdTimestamp: Date?
        /// The attributes of an Endpoint.
        public let endpointAttributes: EndpointAttributes?
        /// The unique identifier of the AppInstanceUserEndpoint.
        public let endpointId: String?
        /// A read-only field that represents the state of an AppInstanceUserEndpoint. Supported values:    ACTIVE: The AppInstanceUserEndpoint is active and able to receive messages. When ACTIVE, the EndpointStatusReason remains empty.    INACTIVE: The AppInstanceUserEndpoint is inactive and can't receive message. When INACTIVE, the corresponding reason will be  conveyed through EndpointStatusReason.    INVALID_DEVICE_TOKEN indicates that an AppInstanceUserEndpoint is INACTIVE due to invalid device token    INVALID_PINPOINT_ARN indicates that an AppInstanceUserEndpoint is INACTIVE due to an invalid pinpoint ARN that was input  through the ResourceArn field.
        public let endpointState: EndpointState?
        /// The time at which an AppInstanceUserEndpoint was last updated.
        public let lastUpdatedTimestamp: Date?
        /// The name of the AppInstanceUserEndpoint.
        public let name: String?
        /// The ARN of the resource to which the endpoint belongs.
        public let resourceArn: String?
        /// The type of the AppInstanceUserEndpoint.
        public let type: AppInstanceUserEndpointType?

        public init(allowMessages: AllowMessages? = nil, appInstanceUserArn: String? = nil, createdTimestamp: Date? = nil, endpointAttributes: EndpointAttributes? = nil, endpointId: String? = nil, endpointState: EndpointState? = nil, lastUpdatedTimestamp: Date? = nil, name: String? = nil, resourceArn: String? = nil, type: AppInstanceUserEndpointType? = nil) {
            self.allowMessages = allowMessages
            self.appInstanceUserArn = appInstanceUserArn
            self.createdTimestamp = createdTimestamp
            self.endpointAttributes = endpointAttributes
            self.endpointId = endpointId
            self.endpointState = endpointState
            self.lastUpdatedTimestamp = lastUpdatedTimestamp
            self.name = name
            self.resourceArn = resourceArn
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case allowMessages = "AllowMessages"
            case appInstanceUserArn = "AppInstanceUserArn"
            case createdTimestamp = "CreatedTimestamp"
            case endpointAttributes = "EndpointAttributes"
            case endpointId = "EndpointId"
            case endpointState = "EndpointState"
            case lastUpdatedTimestamp = "LastUpdatedTimestamp"
            case name = "Name"
            case resourceArn = "ResourceArn"
            case type = "Type"
        }
    }

    public struct AppInstanceUserEndpointSummary: AWSDecodableShape {
        /// BBoolean that controls whether the AppInstanceUserEndpoint is opted in to receive messages. ALL indicates the endpoint will receive all messages.  NONE indicates the endpoint will receive no messages.
        public let allowMessages: AllowMessages?
        /// The ARN of the AppInstanceUser.
        public let appInstanceUserArn: String?
        /// The unique identifier of the AppInstanceUserEndpoint.
        public let endpointId: String?
        /// A read-only field that represent the state of an AppInstanceUserEndpoint.
        public let endpointState: EndpointState?
        /// The name of the AppInstanceUserEndpoint.
        public let name: String?
        /// The type of the AppInstanceUserEndpoint.
        public let type: AppInstanceUserEndpointType?

        public init(allowMessages: AllowMessages? = nil, appInstanceUserArn: String? = nil, endpointId: String? = nil, endpointState: EndpointState? = nil, name: String? = nil, type: AppInstanceUserEndpointType? = nil) {
            self.allowMessages = allowMessages
            self.appInstanceUserArn = appInstanceUserArn
            self.endpointId = endpointId
            self.endpointState = endpointState
            self.name = name
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case allowMessages = "AllowMessages"
            case appInstanceUserArn = "AppInstanceUserArn"
            case endpointId = "EndpointId"
            case endpointState = "EndpointState"
            case name = "Name"
            case type = "Type"
        }
    }

    public struct AppInstanceUserSummary: AWSDecodableShape {
        /// The ARN of the AppInstanceUser.
        public let appInstanceUserArn: String?
        /// The metadata of the AppInstanceUser.
        public let metadata: String?
        /// The name of an AppInstanceUser.
        public let name: String?

        public init(appInstanceUserArn: String? = nil, metadata: String? = nil, name: String? = nil) {
            self.appInstanceUserArn = appInstanceUserArn
            self.metadata = metadata
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceUserArn = "AppInstanceUserArn"
            case metadata = "Metadata"
            case name = "Name"
        }
    }

    public struct ChannelRetentionSettings: AWSEncodableShape & AWSDecodableShape {
        /// The time in days to retain the messages in a channel.
        public let retentionDays: Int?

        public init(retentionDays: Int? = nil) {
            self.retentionDays = retentionDays
        }

        public func validate(name: String) throws {
            try self.validate(self.retentionDays, name: "retentionDays", parent: name, max: 5475)
            try self.validate(self.retentionDays, name: "retentionDays", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case retentionDays = "RetentionDays"
        }
    }

    public struct CreateAppInstanceAdminRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appInstanceArn", location: .uri("AppInstanceArn"))
        ]

        /// The ARN of the administrator of the current AppInstance.
        public let appInstanceAdminArn: String
        /// The ARN of the AppInstance.
        public let appInstanceArn: String

        public init(appInstanceAdminArn: String, appInstanceArn: String) {
            self.appInstanceAdminArn = appInstanceAdminArn
            self.appInstanceArn = appInstanceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.appInstanceAdminArn, name: "appInstanceAdminArn", parent: name, max: 1600)
            try self.validate(self.appInstanceAdminArn, name: "appInstanceAdminArn", parent: name, min: 5)
            try self.validate(self.appInstanceAdminArn, name: "appInstanceAdminArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, max: 1600)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, min: 5)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceAdminArn = "AppInstanceAdminArn"
        }
    }

    public struct CreateAppInstanceAdminResponse: AWSDecodableShape {
        /// The name and ARN of the admin for the AppInstance.
        public let appInstanceAdmin: Identity?
        /// The ARN of the of the admin for the AppInstance.
        public let appInstanceArn: String?

        public init(appInstanceAdmin: Identity? = nil, appInstanceArn: String? = nil) {
            self.appInstanceAdmin = appInstanceAdmin
            self.appInstanceArn = appInstanceArn
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceAdmin = "AppInstanceAdmin"
            case appInstanceArn = "AppInstanceArn"
        }
    }

    public struct CreateAppInstanceRequest: AWSEncodableShape {
        /// The ClientRequestToken of the AppInstance.
        public let clientRequestToken: String
        /// The metadata of the AppInstance. Limited to a 1KB string in UTF-8.
        public let metadata: String?
        /// The name of the AppInstance.
        public let name: String
        /// Tags assigned to the AppInstanceUser.
        public let tags: [Tag]?

        public init(clientRequestToken: String = CreateAppInstanceRequest.idempotencyToken(), metadata: String? = nil, name: String, tags: [Tag]? = nil) {
            self.clientRequestToken = clientRequestToken
            self.metadata = metadata
            self.name = name
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.clientRequestToken, name: "clientRequestToken", parent: name, max: 64)
            try self.validate(self.clientRequestToken, name: "clientRequestToken", parent: name, min: 2)
            try self.validate(self.clientRequestToken, name: "clientRequestToken", parent: name, pattern: "^[-_a-zA-Z0-9]*$")
            try self.validate(self.metadata, name: "metadata", parent: name, max: 1024)
            try self.validate(self.metadata, name: "metadata", parent: name, pattern: ".*")
            try self.validate(self.name, name: "name", parent: name, max: 256)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[\\u0009\\u000A\\u000D\\u0020-\\u007E\\u0085\\u00A0-\\uD7FF\\uE000-\\uFFFD\\u10000-\\u10FFFF]*$")
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case clientRequestToken = "ClientRequestToken"
            case metadata = "Metadata"
            case name = "Name"
            case tags = "Tags"
        }
    }

    public struct CreateAppInstanceResponse: AWSDecodableShape {
        /// The Amazon Resource Number (ARN) of the AppInstance.
        public let appInstanceArn: String?

        public init(appInstanceArn: String? = nil) {
            self.appInstanceArn = appInstanceArn
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceArn = "AppInstanceArn"
        }
    }

    public struct CreateAppInstanceUserRequest: AWSEncodableShape {
        /// The ARN of the AppInstance request.
        public let appInstanceArn: String
        /// The user ID of the AppInstance.
        public let appInstanceUserId: String
        /// The token assigned to the user requesting an AppInstance.
        public let clientRequestToken: String
        /// The request's metadata. Limited to a 1KB string in UTF-8.
        public let metadata: String?
        /// The user's name.
        public let name: String
        /// Tags assigned to the AppInstanceUser.
        public let tags: [Tag]?

        public init(appInstanceArn: String, appInstanceUserId: String, clientRequestToken: String = CreateAppInstanceUserRequest.idempotencyToken(), metadata: String? = nil, name: String, tags: [Tag]? = nil) {
            self.appInstanceArn = appInstanceArn
            self.appInstanceUserId = appInstanceUserId
            self.clientRequestToken = clientRequestToken
            self.metadata = metadata
            self.name = name
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, max: 1600)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, min: 5)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
            try self.validate(self.appInstanceUserId, name: "appInstanceUserId", parent: name, max: 64)
            try self.validate(self.appInstanceUserId, name: "appInstanceUserId", parent: name, min: 1)
            try self.validate(self.appInstanceUserId, name: "appInstanceUserId", parent: name, pattern: "^[A-Za-z0-9]([A-Za-z0-9\\:\\-\\_\\.\\@]{0,62}[A-Za-z0-9])?$")
            try self.validate(self.clientRequestToken, name: "clientRequestToken", parent: name, max: 64)
            try self.validate(self.clientRequestToken, name: "clientRequestToken", parent: name, min: 2)
            try self.validate(self.clientRequestToken, name: "clientRequestToken", parent: name, pattern: "^[-_a-zA-Z0-9]*$")
            try self.validate(self.metadata, name: "metadata", parent: name, max: 1024)
            try self.validate(self.metadata, name: "metadata", parent: name, pattern: ".*")
            try self.validate(self.name, name: "name", parent: name, max: 100)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "\\S")
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceArn = "AppInstanceArn"
            case appInstanceUserId = "AppInstanceUserId"
            case clientRequestToken = "ClientRequestToken"
            case metadata = "Metadata"
            case name = "Name"
            case tags = "Tags"
        }
    }

    public struct CreateAppInstanceUserResponse: AWSDecodableShape {
        /// The user's ARN.
        public let appInstanceUserArn: String?

        public init(appInstanceUserArn: String? = nil) {
            self.appInstanceUserArn = appInstanceUserArn
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceUserArn = "AppInstanceUserArn"
        }
    }

    public struct DeleteAppInstanceAdminRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appInstanceAdminArn", location: .uri("AppInstanceAdminArn")),
            AWSMemberEncoding(label: "appInstanceArn", location: .uri("AppInstanceArn"))
        ]

        /// The ARN of the AppInstance's administrator.
        public let appInstanceAdminArn: String
        /// The ARN of the AppInstance.
        public let appInstanceArn: String

        public init(appInstanceAdminArn: String, appInstanceArn: String) {
            self.appInstanceAdminArn = appInstanceAdminArn
            self.appInstanceArn = appInstanceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.appInstanceAdminArn, name: "appInstanceAdminArn", parent: name, max: 1600)
            try self.validate(self.appInstanceAdminArn, name: "appInstanceAdminArn", parent: name, min: 5)
            try self.validate(self.appInstanceAdminArn, name: "appInstanceAdminArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, max: 1600)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, min: 5)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteAppInstanceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appInstanceArn", location: .uri("AppInstanceArn"))
        ]

        /// The ARN of the AppInstance.
        public let appInstanceArn: String

        public init(appInstanceArn: String) {
            self.appInstanceArn = appInstanceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, max: 1600)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, min: 5)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteAppInstanceUserRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appInstanceUserArn", location: .uri("AppInstanceUserArn"))
        ]

        /// The ARN of the user request being deleted.
        public let appInstanceUserArn: String

        public init(appInstanceUserArn: String) {
            self.appInstanceUserArn = appInstanceUserArn
        }

        public func validate(name: String) throws {
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, max: 1600)
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, min: 5)
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeregisterAppInstanceUserEndpointRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appInstanceUserArn", location: .uri("AppInstanceUserArn")),
            AWSMemberEncoding(label: "endpointId", location: .uri("EndpointId"))
        ]

        /// The ARN of the AppInstanceUser.
        public let appInstanceUserArn: String
        /// The unique identifier of the AppInstanceUserEndpoint.
        public let endpointId: String

        public init(appInstanceUserArn: String, endpointId: String) {
            self.appInstanceUserArn = appInstanceUserArn
            self.endpointId = endpointId
        }

        public func validate(name: String) throws {
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, max: 1600)
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, min: 5)
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
            try self.validate(self.endpointId, name: "endpointId", parent: name, max: 64)
            try self.validate(self.endpointId, name: "endpointId", parent: name, pattern: ".*")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DescribeAppInstanceAdminRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appInstanceAdminArn", location: .uri("AppInstanceAdminArn")),
            AWSMemberEncoding(label: "appInstanceArn", location: .uri("AppInstanceArn"))
        ]

        /// The ARN of the AppInstanceAdmin.
        public let appInstanceAdminArn: String
        /// The ARN of the AppInstance.
        public let appInstanceArn: String

        public init(appInstanceAdminArn: String, appInstanceArn: String) {
            self.appInstanceAdminArn = appInstanceAdminArn
            self.appInstanceArn = appInstanceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.appInstanceAdminArn, name: "appInstanceAdminArn", parent: name, max: 1600)
            try self.validate(self.appInstanceAdminArn, name: "appInstanceAdminArn", parent: name, min: 5)
            try self.validate(self.appInstanceAdminArn, name: "appInstanceAdminArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, max: 1600)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, min: 5)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DescribeAppInstanceAdminResponse: AWSDecodableShape {
        /// The ARN and name of the AppInstanceUser, the ARN of the AppInstance, and the created and last-updated timestamps. All timestamps use epoch milliseconds.
        public let appInstanceAdmin: AppInstanceAdmin?

        public init(appInstanceAdmin: AppInstanceAdmin? = nil) {
            self.appInstanceAdmin = appInstanceAdmin
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceAdmin = "AppInstanceAdmin"
        }
    }

    public struct DescribeAppInstanceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appInstanceArn", location: .uri("AppInstanceArn"))
        ]

        /// The ARN of the AppInstance.
        public let appInstanceArn: String

        public init(appInstanceArn: String) {
            self.appInstanceArn = appInstanceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, max: 1600)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, min: 5)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DescribeAppInstanceResponse: AWSDecodableShape {
        /// The ARN, metadata, created and last-updated timestamps, and the name of the AppInstance. All timestamps use epoch milliseconds.
        public let appInstance: AppInstance?

        public init(appInstance: AppInstance? = nil) {
            self.appInstance = appInstance
        }

        private enum CodingKeys: String, CodingKey {
            case appInstance = "AppInstance"
        }
    }

    public struct DescribeAppInstanceUserEndpointRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appInstanceUserArn", location: .uri("AppInstanceUserArn")),
            AWSMemberEncoding(label: "endpointId", location: .uri("EndpointId"))
        ]

        /// The ARN of the AppInstanceUser.
        public let appInstanceUserArn: String
        /// The unique identifier of the AppInstanceUserEndpoint.
        public let endpointId: String

        public init(appInstanceUserArn: String, endpointId: String) {
            self.appInstanceUserArn = appInstanceUserArn
            self.endpointId = endpointId
        }

        public func validate(name: String) throws {
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, max: 1600)
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, pattern: ".*")
            try self.validate(self.endpointId, name: "endpointId", parent: name, max: 64)
            try self.validate(self.endpointId, name: "endpointId", parent: name, pattern: ".*")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DescribeAppInstanceUserEndpointResponse: AWSDecodableShape {
        /// The full details of an AppInstanceUserEndpoint: the AppInstanceUserArn, ID, name, type, resource ARN, attributes,  allow messages, state, and created and last updated timestamps. All timestamps use epoch milliseconds.
        public let appInstanceUserEndpoint: AppInstanceUserEndpoint?

        public init(appInstanceUserEndpoint: AppInstanceUserEndpoint? = nil) {
            self.appInstanceUserEndpoint = appInstanceUserEndpoint
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceUserEndpoint = "AppInstanceUserEndpoint"
        }
    }

    public struct DescribeAppInstanceUserRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appInstanceUserArn", location: .uri("AppInstanceUserArn"))
        ]

        /// The ARN of the AppInstanceUser.
        public let appInstanceUserArn: String

        public init(appInstanceUserArn: String) {
            self.appInstanceUserArn = appInstanceUserArn
        }

        public func validate(name: String) throws {
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, max: 1600)
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, min: 5)
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DescribeAppInstanceUserResponse: AWSDecodableShape {
        /// The name of the AppInstanceUser.
        public let appInstanceUser: AppInstanceUser?

        public init(appInstanceUser: AppInstanceUser? = nil) {
            self.appInstanceUser = appInstanceUser
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceUser = "AppInstanceUser"
        }
    }

    public struct EndpointAttributes: AWSEncodableShape & AWSDecodableShape {
        /// The device token for the GCM, APNS, and APNS_SANDBOX endpoint types.
        public let deviceToken: String
        /// The VOIP device token for the APNS and APNS_SANDBOX endpoint types.
        public let voipDeviceToken: String?

        public init(deviceToken: String, voipDeviceToken: String? = nil) {
            self.deviceToken = deviceToken
            self.voipDeviceToken = voipDeviceToken
        }

        public func validate(name: String) throws {
            try self.validate(self.deviceToken, name: "deviceToken", parent: name, max: 1600)
            try self.validate(self.deviceToken, name: "deviceToken", parent: name, min: 1)
            try self.validate(self.deviceToken, name: "deviceToken", parent: name, pattern: ".*")
            try self.validate(self.voipDeviceToken, name: "voipDeviceToken", parent: name, max: 1600)
            try self.validate(self.voipDeviceToken, name: "voipDeviceToken", parent: name, min: 1)
            try self.validate(self.voipDeviceToken, name: "voipDeviceToken", parent: name, pattern: ".*")
        }

        private enum CodingKeys: String, CodingKey {
            case deviceToken = "DeviceToken"
            case voipDeviceToken = "VoipDeviceToken"
        }
    }

    public struct EndpointState: AWSDecodableShape {
        /// Enum that indicates the Status of an AppInstanceUserEndpoint.
        public let status: EndpointStatus
        /// The reason for the EndpointStatus.
        public let statusReason: EndpointStatusReason?

        public init(status: EndpointStatus, statusReason: EndpointStatusReason? = nil) {
            self.status = status
            self.statusReason = statusReason
        }

        private enum CodingKeys: String, CodingKey {
            case status = "Status"
            case statusReason = "StatusReason"
        }
    }

    public struct GetAppInstanceRetentionSettingsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appInstanceArn", location: .uri("AppInstanceArn"))
        ]

        /// The ARN of the AppInstance.
        public let appInstanceArn: String

        public init(appInstanceArn: String) {
            self.appInstanceArn = appInstanceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, max: 1600)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, min: 5)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct GetAppInstanceRetentionSettingsResponse: AWSDecodableShape {
        /// The retention settings for the AppInstance.
        public let appInstanceRetentionSettings: AppInstanceRetentionSettings?
        /// The timestamp representing the time at which the specified items are retained, in Epoch Seconds.
        public let initiateDeletionTimestamp: Date?

        public init(appInstanceRetentionSettings: AppInstanceRetentionSettings? = nil, initiateDeletionTimestamp: Date? = nil) {
            self.appInstanceRetentionSettings = appInstanceRetentionSettings
            self.initiateDeletionTimestamp = initiateDeletionTimestamp
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceRetentionSettings = "AppInstanceRetentionSettings"
            case initiateDeletionTimestamp = "InitiateDeletionTimestamp"
        }
    }

    public struct Identity: AWSDecodableShape {
        /// The ARN in an Identity.
        public let arn: String?
        /// The name in an Identity.
        public let name: String?

        public init(arn: String? = nil, name: String? = nil) {
            self.arn = arn
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case name = "Name"
        }
    }

    public struct ListAppInstanceAdminsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appInstanceArn", location: .uri("AppInstanceArn")),
            AWSMemberEncoding(label: "maxResults", location: .querystring("max-results")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("next-token"))
        ]

        /// The ARN of the AppInstance.
        public let appInstanceArn: String
        /// The maximum number of administrators that you want to return.
        public let maxResults: Int?
        /// The token returned from previous API requests until the number of administrators is reached.
        public let nextToken: String?

        public init(appInstanceArn: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.appInstanceArn = appInstanceArn
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, max: 1600)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, min: 5)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: ".*")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListAppInstanceAdminsResponse: AWSDecodableShape {
        /// The information for each administrator.
        public let appInstanceAdmins: [AppInstanceAdminSummary]?
        /// The ARN of the AppInstance.
        public let appInstanceArn: String?
        /// The token returned from previous API requests until the number of administrators is reached.
        public let nextToken: String?

        public init(appInstanceAdmins: [AppInstanceAdminSummary]? = nil, appInstanceArn: String? = nil, nextToken: String? = nil) {
            self.appInstanceAdmins = appInstanceAdmins
            self.appInstanceArn = appInstanceArn
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceAdmins = "AppInstanceAdmins"
            case appInstanceArn = "AppInstanceArn"
            case nextToken = "NextToken"
        }
    }

    public struct ListAppInstanceUserEndpointsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appInstanceUserArn", location: .uri("AppInstanceUserArn")),
            AWSMemberEncoding(label: "maxResults", location: .querystring("max-results")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("next-token"))
        ]

        /// The ARN of the AppInstanceUser.
        public let appInstanceUserArn: String
        /// The maximum number of endpoints that you want to return.
        public let maxResults: Int?
        /// The token passed by previous API calls until all requested endpoints are returned.
        public let nextToken: String?

        public init(appInstanceUserArn: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.appInstanceUserArn = appInstanceUserArn
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, max: 1600)
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, min: 5)
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: ".*")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListAppInstanceUserEndpointsResponse: AWSDecodableShape {
        /// The information for each requested AppInstanceUserEndpoint.
        public let appInstanceUserEndpoints: [AppInstanceUserEndpointSummary]?
        /// The token passed by previous API calls until all requested endpoints are returned.
        public let nextToken: String?

        public init(appInstanceUserEndpoints: [AppInstanceUserEndpointSummary]? = nil, nextToken: String? = nil) {
            self.appInstanceUserEndpoints = appInstanceUserEndpoints
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceUserEndpoints = "AppInstanceUserEndpoints"
            case nextToken = "NextToken"
        }
    }

    public struct ListAppInstanceUsersRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appInstanceArn", location: .querystring("app-instance-arn")),
            AWSMemberEncoding(label: "maxResults", location: .querystring("max-results")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("next-token"))
        ]

        /// The ARN of the AppInstance.
        public let appInstanceArn: String
        /// The maximum number of requests that you want returned.
        public let maxResults: Int?
        /// The token passed by previous API calls until all requested users are returned.
        public let nextToken: String?

        public init(appInstanceArn: String, maxResults: Int? = nil, nextToken: String? = nil) {
            self.appInstanceArn = appInstanceArn
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, max: 1600)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, min: 5)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: ".*")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListAppInstanceUsersResponse: AWSDecodableShape {
        /// The ARN of the AppInstance.
        public let appInstanceArn: String?
        /// The information for each requested AppInstanceUser.
        public let appInstanceUsers: [AppInstanceUserSummary]?
        /// The token passed by previous API calls until all requested users are returned.
        public let nextToken: String?

        public init(appInstanceArn: String? = nil, appInstanceUsers: [AppInstanceUserSummary]? = nil, nextToken: String? = nil) {
            self.appInstanceArn = appInstanceArn
            self.appInstanceUsers = appInstanceUsers
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceArn = "AppInstanceArn"
            case appInstanceUsers = "AppInstanceUsers"
            case nextToken = "NextToken"
        }
    }

    public struct ListAppInstancesRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "maxResults", location: .querystring("max-results")),
            AWSMemberEncoding(label: "nextToken", location: .querystring("next-token"))
        ]

        /// The maximum number of AppInstances that you want to return.
        public let maxResults: Int?
        /// The token passed by previous API requests until you reach the maximum number of AppInstances.
        public let nextToken: String?

        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 2048)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: ".*")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListAppInstancesResponse: AWSDecodableShape {
        /// The information for each AppInstance.
        public let appInstances: [AppInstanceSummary]?
        /// The token passed by previous API requests until the maximum number of AppInstances is reached.
        public let nextToken: String?

        public init(appInstances: [AppInstanceSummary]? = nil, nextToken: String? = nil) {
            self.appInstances = appInstances
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case appInstances = "AppInstances"
            case nextToken = "NextToken"
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceARN", location: .querystring("arn"))
        ]

        /// The ARN of the resource.
        public let resourceARN: String

        public init(resourceARN: String) {
            self.resourceARN = resourceARN
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, max: 1600)
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, min: 5)
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// The tag key-value pairs.
        public let tags: [Tag]?

        public init(tags: [Tag]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "Tags"
        }
    }

    public struct PutAppInstanceRetentionSettingsRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appInstanceArn", location: .uri("AppInstanceArn"))
        ]

        /// The ARN of the AppInstance.
        public let appInstanceArn: String
        /// The time in days to retain data. Data type: number.
        public let appInstanceRetentionSettings: AppInstanceRetentionSettings

        public init(appInstanceArn: String, appInstanceRetentionSettings: AppInstanceRetentionSettings) {
            self.appInstanceArn = appInstanceArn
            self.appInstanceRetentionSettings = appInstanceRetentionSettings
        }

        public func validate(name: String) throws {
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, max: 1600)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, min: 5)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
            try self.appInstanceRetentionSettings.validate(name: "\(name).appInstanceRetentionSettings")
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceRetentionSettings = "AppInstanceRetentionSettings"
        }
    }

    public struct PutAppInstanceRetentionSettingsResponse: AWSDecodableShape {
        /// The time in days to retain data. Data type: number.
        public let appInstanceRetentionSettings: AppInstanceRetentionSettings?
        /// The time at which the API deletes data.
        public let initiateDeletionTimestamp: Date?

        public init(appInstanceRetentionSettings: AppInstanceRetentionSettings? = nil, initiateDeletionTimestamp: Date? = nil) {
            self.appInstanceRetentionSettings = appInstanceRetentionSettings
            self.initiateDeletionTimestamp = initiateDeletionTimestamp
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceRetentionSettings = "AppInstanceRetentionSettings"
            case initiateDeletionTimestamp = "InitiateDeletionTimestamp"
        }
    }

    public struct RegisterAppInstanceUserEndpointRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appInstanceUserArn", location: .uri("AppInstanceUserArn"))
        ]

        /// Boolean that controls whether the AppInstanceUserEndpoint is opted in to receive messages. ALL indicates the endpoint receives all messages.  NONE indicates the endpoint receives no messages.
        public let allowMessages: AllowMessages?
        /// The ARN of the AppInstanceUser.
        public let appInstanceUserArn: String
        /// The idempotency token for each client request.
        public let clientRequestToken: String
        /// The attributes of an Endpoint.
        public let endpointAttributes: EndpointAttributes
        /// The name of the AppInstanceUserEndpoint.
        public let name: String?
        /// The ARN of the resource to which the endpoint belongs.
        public let resourceArn: String
        /// The type of the AppInstanceUserEndpoint. Supported types:    APNS: The mobile notification service for an Apple device.    APNS_SANDBOX: The sandbox environment of the mobile notification service for an Apple device.    GCM: The mobile notification service for an Android device.   Populate the ResourceArn value of each type as PinpointAppArn.
        public let type: AppInstanceUserEndpointType

        public init(allowMessages: AllowMessages? = nil, appInstanceUserArn: String, clientRequestToken: String = RegisterAppInstanceUserEndpointRequest.idempotencyToken(), endpointAttributes: EndpointAttributes, name: String? = nil, resourceArn: String, type: AppInstanceUserEndpointType) {
            self.allowMessages = allowMessages
            self.appInstanceUserArn = appInstanceUserArn
            self.clientRequestToken = clientRequestToken
            self.endpointAttributes = endpointAttributes
            self.name = name
            self.resourceArn = resourceArn
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, max: 1600)
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, min: 5)
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
            try self.validate(self.clientRequestToken, name: "clientRequestToken", parent: name, max: 64)
            try self.validate(self.clientRequestToken, name: "clientRequestToken", parent: name, min: 2)
            try self.validate(self.clientRequestToken, name: "clientRequestToken", parent: name, pattern: "^[-_a-zA-Z0-9]*$")
            try self.endpointAttributes.validate(name: "\(name).endpointAttributes")
            try self.validate(self.name, name: "name", parent: name, max: 1600)
            try self.validate(self.name, name: "name", parent: name, pattern: ".*")
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 1600)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 5)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
        }

        private enum CodingKeys: String, CodingKey {
            case allowMessages = "AllowMessages"
            case clientRequestToken = "ClientRequestToken"
            case endpointAttributes = "EndpointAttributes"
            case name = "Name"
            case resourceArn = "ResourceArn"
            case type = "Type"
        }
    }

    public struct RegisterAppInstanceUserEndpointResponse: AWSDecodableShape {
        /// The ARN of the AppInstanceUser.
        public let appInstanceUserArn: String?
        /// The unique identifier of the AppInstanceUserEndpoint.
        public let endpointId: String?

        public init(appInstanceUserArn: String? = nil, endpointId: String? = nil) {
            self.appInstanceUserArn = appInstanceUserArn
            self.endpointId = endpointId
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceUserArn = "AppInstanceUserArn"
            case endpointId = "EndpointId"
        }
    }

    public struct Tag: AWSEncodableShape & AWSDecodableShape {
        /// The key in a tag.
        public let key: String
        /// The value in a tag.
        public let value: String

        public init(key: String, value: String) {
            self.key = key
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 128)
            try self.validate(self.key, name: "key", parent: name, min: 1)
            try self.validate(self.value, name: "value", parent: name, max: 256)
            try self.validate(self.value, name: "value", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case key = "Key"
            case value = "Value"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        /// The resource ARN.
        public let resourceARN: String
        /// The tag key-value pairs.
        public let tags: [Tag]

        public init(resourceARN: String, tags: [Tag]) {
            self.resourceARN = resourceARN
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, max: 1600)
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, min: 5)
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
            try self.tags.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceARN = "ResourceARN"
            case tags = "Tags"
        }
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        /// The resource ARN.
        public let resourceARN: String
        /// The tag keys.
        public let tagKeys: [String]

        public init(resourceARN: String, tagKeys: [String]) {
            self.resourceARN = resourceARN
            self.tagKeys = tagKeys
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, max: 1600)
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, min: 5)
            try self.validate(self.resourceARN, name: "resourceARN", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 50)
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceARN = "ResourceARN"
            case tagKeys = "TagKeys"
        }
    }

    public struct UpdateAppInstanceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appInstanceArn", location: .uri("AppInstanceArn"))
        ]

        /// The ARN of the AppInstance.
        public let appInstanceArn: String
        /// The metadata that you want to change.
        public let metadata: String
        /// The name that you want to change.
        public let name: String

        public init(appInstanceArn: String, metadata: String, name: String) {
            self.appInstanceArn = appInstanceArn
            self.metadata = metadata
            self.name = name
        }

        public func validate(name: String) throws {
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, max: 1600)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, min: 5)
            try self.validate(self.appInstanceArn, name: "appInstanceArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
            try self.validate(self.metadata, name: "metadata", parent: name, max: 1024)
            try self.validate(self.metadata, name: "metadata", parent: name, pattern: ".*")
            try self.validate(self.name, name: "name", parent: name, max: 256)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[\\u0009\\u000A\\u000D\\u0020-\\u007E\\u0085\\u00A0-\\uD7FF\\uE000-\\uFFFD\\u10000-\\u10FFFF]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case metadata = "Metadata"
            case name = "Name"
        }
    }

    public struct UpdateAppInstanceResponse: AWSDecodableShape {
        /// The ARN of the AppInstance.
        public let appInstanceArn: String?

        public init(appInstanceArn: String? = nil) {
            self.appInstanceArn = appInstanceArn
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceArn = "AppInstanceArn"
        }
    }

    public struct UpdateAppInstanceUserEndpointRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appInstanceUserArn", location: .uri("AppInstanceUserArn")),
            AWSMemberEncoding(label: "endpointId", location: .uri("EndpointId"))
        ]

        /// Boolean that controls whether the AppInstanceUserEndpoint is opted in to receive messages. ALL indicates the endpoint will receive all messages.  NONE indicates the endpoint will receive no messages.
        public let allowMessages: AllowMessages?
        /// The ARN of the AppInstanceUser.
        public let appInstanceUserArn: String
        /// The unique identifier of the AppInstanceUserEndpoint.
        public let endpointId: String
        /// The name of the AppInstanceUserEndpoint.
        public let name: String?

        public init(allowMessages: AllowMessages? = nil, appInstanceUserArn: String, endpointId: String, name: String? = nil) {
            self.allowMessages = allowMessages
            self.appInstanceUserArn = appInstanceUserArn
            self.endpointId = endpointId
            self.name = name
        }

        public func validate(name: String) throws {
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, max: 1600)
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, min: 5)
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
            try self.validate(self.endpointId, name: "endpointId", parent: name, max: 64)
            try self.validate(self.endpointId, name: "endpointId", parent: name, pattern: ".*")
            try self.validate(self.name, name: "name", parent: name, max: 1600)
            try self.validate(self.name, name: "name", parent: name, pattern: ".*")
        }

        private enum CodingKeys: String, CodingKey {
            case allowMessages = "AllowMessages"
            case name = "Name"
        }
    }

    public struct UpdateAppInstanceUserEndpointResponse: AWSDecodableShape {
        /// The ARN of the AppInstanceUser.
        public let appInstanceUserArn: String?
        /// The unique identifier of the AppInstanceUserEndpoint.
        public let endpointId: String?

        public init(appInstanceUserArn: String? = nil, endpointId: String? = nil) {
            self.appInstanceUserArn = appInstanceUserArn
            self.endpointId = endpointId
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceUserArn = "AppInstanceUserArn"
            case endpointId = "EndpointId"
        }
    }

    public struct UpdateAppInstanceUserRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "appInstanceUserArn", location: .uri("AppInstanceUserArn"))
        ]

        /// The ARN of the AppInstanceUser.
        public let appInstanceUserArn: String
        /// The metadata of the AppInstanceUser.
        public let metadata: String
        /// The name of the AppInstanceUser.
        public let name: String

        public init(appInstanceUserArn: String, metadata: String, name: String) {
            self.appInstanceUserArn = appInstanceUserArn
            self.metadata = metadata
            self.name = name
        }

        public func validate(name: String) throws {
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, max: 1600)
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, min: 5)
            try self.validate(self.appInstanceUserArn, name: "appInstanceUserArn", parent: name, pattern: "^arn:[a-z0-9-\\.]{1,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[a-z0-9-\\.]{0,63}:[^/].{0,1023}$")
            try self.validate(self.metadata, name: "metadata", parent: name, max: 1024)
            try self.validate(self.metadata, name: "metadata", parent: name, pattern: ".*")
            try self.validate(self.name, name: "name", parent: name, max: 100)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, pattern: "\\S")
        }

        private enum CodingKeys: String, CodingKey {
            case metadata = "Metadata"
            case name = "Name"
        }
    }

    public struct UpdateAppInstanceUserResponse: AWSDecodableShape {
        /// The ARN of the AppInstanceUser.
        public let appInstanceUserArn: String?

        public init(appInstanceUserArn: String? = nil) {
            self.appInstanceUserArn = appInstanceUserArn
        }

        private enum CodingKeys: String, CodingKey {
            case appInstanceUserArn = "AppInstanceUserArn"
        }
    }
}

// MARK: - Errors

/// Error enum for ChimeSDKIdentity
public struct ChimeSDKIdentityErrorType: AWSErrorType {
    enum Code: String {
        case badRequestException = "BadRequestException"
        case conflictException = "ConflictException"
        case forbiddenException = "ForbiddenException"
        case resourceLimitExceededException = "ResourceLimitExceededException"
        case serviceFailureException = "ServiceFailureException"
        case serviceUnavailableException = "ServiceUnavailableException"
        case throttledClientException = "ThrottledClientException"
        case unauthorizedClientException = "UnauthorizedClientException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize ChimeSDKIdentity
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// The input parameters don&#39;t match the service&#39;s restrictions.
    public static var badRequestException: Self { .init(.badRequestException) }
    /// The request could not be processed because of conflict in the current state of the resource.
    public static var conflictException: Self { .init(.conflictException) }
    /// The client is permanently forbidden from making the request.
    public static var forbiddenException: Self { .init(.forbiddenException) }
    /// The request exceeds the resource limit.
    public static var resourceLimitExceededException: Self { .init(.resourceLimitExceededException) }
    /// The service encountered an unexpected error.
    public static var serviceFailureException: Self { .init(.serviceFailureException) }
    /// The service is currently unavailable.
    public static var serviceUnavailableException: Self { .init(.serviceUnavailableException) }
    /// The client exceeded its request rate limit.
    public static var throttledClientException: Self { .init(.throttledClientException) }
    /// The client is not currently authorized to make the request.
    public static var unauthorizedClientException: Self { .init(.unauthorizedClientException) }
}

extension ChimeSDKIdentityErrorType: Equatable {
    public static func == (lhs: ChimeSDKIdentityErrorType, rhs: ChimeSDKIdentityErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension ChimeSDKIdentityErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
